﻿using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Web.Http;
using Sustainalytics.Claims;
using Sustainalytics.DataLayer.ConnectionStrings;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.Governance.BusinessLogic;
using Sustainalytics.Governance.BusinessLogic.Exceptions;
using Sustainalytics.Utils;
using WebApi.OutputCache.V2;
using Sustainalytics.Entities;
using Sustainalytics.Entities.Governance;
using Sustainalytics.Governance.BusinessLogic.Model;
using System.Web.Http.Cors;

namespace Sustainalytics.Governance.Service
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/v1/governanceadmin")]
    [LogControllerFilter(true, true, false)]
    public class GovernanceAdminController : ApiController
    {
        private IGovernanceManager _gManager;
        static IClaimsChecker _claimsChecker;
        
        public GovernanceAdminController()
        {
           
            var connectionString = ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;
            var connectionStringsManager =
                ConnectionStringsManager.GetInstance(ConnectionStringsRepository.GetInstance(connectionString));
            var clientDwConnectionString = connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW);
            var governanceDwConnectionString = connectionStringsManager.GetConnectionString(ConnectionStringType.GovernanceDW);
            var governanceInputFileConnectionString = ConfigurationManager.ConnectionStrings["GovernanceInputFile"].ConnectionString;

            _gManager = GovernanceManager.CreateGovernanceManager(clientDwConnectionString, governanceDwConnectionString, governanceInputFileConnectionString);
            
        }

        static GovernanceAdminController()
        {
            _claimsChecker = new ClaimsChecker();
        }
        public GovernanceAdminController(IGovernanceManager gManager, IClaimsChecker claimsChecker)
        {
            _gManager = gManager;
            _claimsChecker = claimsChecker;
        }

        
        [Route("{id}")]
        public HttpResponseMessage Get(Guid id)
        {
            HttpResponseMessage response;
            try
            {
                //claims for Company Assessment online report and at least one PI indicator claim
                if (!_claimsChecker.ValidateGovernanceClaim(this))
                {
                    return this.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }

                var claims = ClaimsPrincipal.Current.Claims;

                var result = _gManager.GetProfileByCompany(id);
                
                response = Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (GovernanceProfileNotFoundException ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                response = Request.CreateResponse(HttpStatusCode.OK, new { errorCode = 7000 });
            }    
            catch (GovernanceProfileNotInUniversesException ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                response = Request.CreateResponse(HttpStatusCode.OK, new { errorCode = 7001 });
            }
            catch (Exception ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }            
            return response;
        }

        //can be used to add / edit profiles and add / edit / remove associated alerts
        [HttpPost]
        [Route("")]
        public HttpResponseMessage Post([FromBody] GovernanceInsightDto insightDto)
        {
            try
            {
                if (!_claimsChecker.ValidateGovernanceClaim(this))
                {
                    return this.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }

                var userName = (User == null || User.Identity == null ? null : User.Identity.Name);
                
                Guid insightId = (insightDto.Id == null || insightDto.Id == Guid.Empty) ? Guid.NewGuid() : insightDto.Id;

                GovernanceInsight insight = new GovernanceInsight()
                {
                    Id = insightId,
                    FileId = insightDto.FileId,
                    PublicationDate = insightDto.PublicationDate,
                    Title = insightDto.Title,
                    CreatedBy = userName,
                    CreatedDate = DateTime.UtcNow
                };

                GovernanceInsightInputFile inputFile = new GovernanceInsightInputFile()
                {
                    CompanyId = insightDto.CompanyId,
                    Id = Guid.NewGuid(),
                    FileName = insightDto.FileName,
                    FileId = insightDto.FileId,
                    CreationTimeStamp = DateTime.UtcNow,
                    PublicationDate = insightDto.PublicationDate,
                    CreatedBy = userName,
                    Title = insightDto.Title,
                };

                var result = _gManager.AddInsight(insight, inputFile);

                //invalidate cache for parent resource 
                var cache = Configuration.CacheOutputConfiguration().GetCacheOutputProvider(Request);
                cache.RemoveStartsWith(Configuration.CacheOutputConfiguration().MakeBaseCachekey("Companies", "Get"));
                
                return Request.CreateResponse(HttpStatusCode.Created, result);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
            }
            catch (Exception ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
   
        //removes the insight
        [HttpDelete]
        [Route("{id}")]
        public HttpResponseMessage Delete(Guid id, [FromUri] Guid companyId)
        {
            try
            {
                if (!_claimsChecker.ValidateGovernanceClaim(this))
                {
                    return this.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }

                _gManager.DeleteInsight(id, companyId);
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    }
}

